/******************************************************************************
 cnome: A C++ source "genes" discover. :-)

 See more details at:

   http://www.codeplex.com/cnome

 The original author site is at: http://www.alexandre-barbosa.com/

 Copyright (c) 2008 Alexandre Barbosa.
 Distributed under the MIT License. (See accompanying file LICENSE-MIT.txt 
 or at http://www.codeplex.com/cnome/license)
 ******************************************************************************/

#ifndef DIRECTIVE_LRS_H
#define DIRECTIVE_LRS_H

#include "directive_base.h"
#include "variables.h"

namespace cnome { namespace directive {

    struct lrs_parser_gen;

    template <typename ParserT>
    struct lrs
    :   public boost::spirit::classic::unary<ParserT, boost::spirit::classic::parser<lrs<ParserT> > > 
    {
        typedef lrs<ParserT>                    self_t;
        typedef  boost::spirit::classic::unary_parser_category           parser_category_t;
        typedef lrs_parser_gen                  parser_generator_t;
        typedef boost::spirit::classic::unary<ParserT, boost::spirit::classic::parser<self_t> > base_t;

        lrs(ParserT const& p)
        : base_t(p) {}

        template <typename ScannerT>
        typename boost::spirit::classic::parser_result<self_t, ScannerT>::type
        parse(ScannerT const& scan) const
        {
            typedef typename boost::spirit::classic::parser_result<self_t, ScannerT>::type result_t;
            return impl::drt_parser_parse<result_t>
                //(this->subject(), scan, scan);
                (*this, scan, scan);
        }

        const char* MyName() const { return "lrs"; }

        template <typename ScannerT>
        inline void
        deriv_action_before_parse(
            ScannerT const& scan) const
        {
            lstSzScp = var::l_scope.size();
            if (lstSzScp)
            {
               auxscope=var::scope;
               auxl_scope=var::l_scope.back();
               var::l_scope.pop_back();
               var::scope=var::l_scope.back();
			   wasScopeAbsolut = var::isScopeAbsolut;
            }
        }

        template <typename ScannerT>
        inline void
        deriv_action_after_parse(
            ScannerT const& scan) const
        {
            if (lstSzScp)
            {
               var::l_scope.push_back(auxl_scope);
               var::scope=auxscope;
			   var::isScopeAbsolut = wasScopeAbsolut;
            }
            else
			{
                var::l_scope.clear();
				var::isScopeAbsolut = false;
			}
        }

    private:
        mutable scopeT auxscope;
        mutable scopeT auxl_scope;
        mutable std::size_t lstSzScp;
		mutable bool wasScopeAbsolut;
    };

    //////////////////////////////////
    const drt_parser_gen<lrs> last_remain_scope_d = drt_parser_gen<lrs>();

}} // namespace cnome { namespace directive {

#endif  // DIRECTIVE_LRS_H
